﻿// <copyright file="MainWindow.cs" company="non commercial use">
// Copyright (c) 5/4/2012 All Right Reserved
// </copyright>
// <author>Dimitry Kaplin</author>
// <date>5/4/2012 2:20 </date>
// <summary>Main window logic</summary>

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using EthernetTools.UI.Dialogs;

namespace EthernetTools
{
    public partial class MainWindow : Form
    {
        /// <summary>
        /// Instance of Main Window
        /// </summary>
        public static MainWindow Instance { get; private set; }

        /// <summary>
        /// Binded adapter ID
        /// </summary>
        public static string BindedAdapterId
        {
            get;
            private set;
        }

        /// <summary>
        /// Instance of Interface to Ethernet  Adapter
        /// </summary>
        public RawEthernet.RawEthernet RawEtherInstance
        {
            get;
            private set;
        }

        /// <summary>
        /// Event for checking service state
        /// </summary>
        private AutoResetEvent ServiceStateEvent = new AutoResetEvent(false);

        /// <summary>
        /// service state check times
        /// </summary>
        private int CurrentTimes = 0;

        /// <summary>
        /// Timeout in secs.
        /// </summary>
        private int TimeOut = 5;

        /// <summary>
        /// State for what we waiting
        /// </summary>
        private Utils.ServiceMangerInternal.ServiceCurrentState WaitingState;

        /// <summary>
        /// Autoscrolling stuff
        /// </summary>
        private int caretPosition;

        /// <summary>
        /// Log by levels (Here duplicate data)
        /// </summary>
        private static Dictionary<Options.Global.LogLevel, List<string>> OutputMessages = new Dictionary<Options.Global.LogLevel, List<string>>();

        /// <summary>
        /// Selected adapter info
        /// </summary>
        private RawEthernet.AdaptersInfo selectedAi;

        public MainWindow()
        {
            if (Instance != null)
            {
                MessageBox.Show(this, "Sorry the only one instance of main window is allowed.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                this.Close();
            }
            else
            {
                InitializeComponent();

                toolStripMenuItem_autoscrollLog.CheckedChanged += new EventHandler(toolStripMenuItem_autoscrollLog_CheckedChanged);

                EthernetTools.Utils.ByteUtils.LogWriteDelegate = LogWriteLine;

                InitLogLevelOptions();
               
                Instance = this;
            }
        }

        #region Methods

        #region Methods : Adapter

        /// <summary>
        /// Open driver handle
        /// </summary>
        private void InitAdapter()
        {
            RawEtherInstance = new RawEthernet.RawEthernet();

            // check to see if we got a valid handle
            if (RawEtherInstance.IsDriverOpen)
            {
                // we have a handle to the device
                LogWriteLine("Handle to NDIS Driver: " + RawEtherInstance.Handle.ToString(), Options.Global.LogLevel.Info);
            }
            else
            {
                // we don't have a handle so alert user and quit
                LogWriteLine("ERROR: NDIS Driver could not be opened\n", Options.Global.LogLevel.Error);
                return;
            }

            // OK, now we have a handle to the driver, so let's get a list of the
            // adapters that are using that driver
            RawEthernet.AdaptersInfo[] aiAdapters = RawEtherInstance.EnumerateAdapters();
            // List the adapters so that we can choose which one we want to use
            LogWriteLine("\nThe following adapters can be used to send packets:", Options.Global.LogLevel.Info);

            listBox_adapters.Items.AddRange(aiAdapters);

            // Ask the user to choose the index of the adapter that they want to send from
            LogWriteLine("\nChoose the adapter that you want to send from: ", Options.Global.LogLevel.Info);

        }

        /// <summary>
        /// Close driver
        /// </summary>
        private void CloseAdapter()
        {
            RawEtherInstance.CloseDriver();

            BindedAdapterId = "";

            this.selectedAi = null;

            listBox_adapters.Items.Clear();
            listBox_adapters.Enabled = true;

            EthernetTools.UI.TabPppoeAcMap.StopReadingThread();
            foreach (Control c in tabPage_pppoeSending.Controls)
            {
                c.Dispose();
            }

            foreach (Control c in tabPage_AC_MAP.Controls)
            {
                c.Dispose();
            }

            foreach (Control c in tabPage_Abs_raw_send.Controls)
            {
                c.Dispose();
            }
        }

        /// <summary>
        /// Bind to selected abaptor in list
        /// </summary>
        private void BindAdapter()
        {
            this.selectedAi = (RawEthernet.AdaptersInfo)listBox_adapters.SelectedItem;
            if (this.selectedAi == null)
            {
                return;
            }

            // ok, now bind that adapter to the driver handle that we have open
            if (!RawEtherInstance.BindAdapter(this.selectedAi.AdapterID))
            {
                // alert user and quit
                LogWriteLine("ERROR: Could not bind to the adapter \"" + this.selectedAi.AdapterID + "\".\n", Options.Global.LogLevel.Error);
                return;
            }
            else
            {
                // tell the user that we are bound to the adapter
                LogWriteLine("\nAdapter " + this.selectedAi.AdapterID +
                    " is ready for writing...\n", Options.Global.LogLevel.Info);

                this.listBox_adapters.Enabled = false;

                MainWindow.BindedAdapterId = this.selectedAi.AdapterID;

                tabPage_pppoeSending.Controls.Clear();
                tabPage_pppoeSending.Controls.Add(new UI.TabSendPPPoE());

                tabPage_AC_MAP.Controls.Clear();
                tabPage_AC_MAP.Controls.Add(new UI.TabPppoeAcMap());

                tabPage_Abs_raw_send.Controls.Clear();
                tabPage_Abs_raw_send.Controls.Add(new UI.TabAbsRawSend());
            }
        }

        #endregion

        #region Methods : Service

        /// <summary>
        /// Starts Service
        /// </summary>
        private void StartService()
        {
            try
            {

                CheckServiceSatus();
                if (Utils.ServiceMangerInternal.LastServiceStatus.dwCurrentState == (int)Utils.ServiceMangerInternal.ServiceCurrentState.SERVICE_PAUSED)
                {
                    ContinueService();
                }
                else if (Utils.ServiceMangerInternal.LastServiceStatus.dwCurrentState == (int)Utils.ServiceMangerInternal.ServiceCurrentState.SERVICE_STOPPED)
                {
                    LogWriteLine("Starting ndisprot", Options.Global.LogLevel.Info); 

                    CloseAdapter();

                    if (Utils.ServiceMangerInternal.StartService(Utils.ServiceMangerInternal.NdisProtServiceName))
                    {
                        LogWriteLine("Success", Options.Global.LogLevel.Info);

                        listBox_adapters.Items.Clear();

                        WaitForServiceState(Utils.ServiceMangerInternal.ServiceCurrentState.SERVICE_RUNNING, 2);

                        InitAdapter();

                        CheckServiceSatus();
                    }
                }
                else
                {
                    LogWriteLine("Not supported service state for starting", Options.Global.LogLevel.Error);
                }
            }
            catch (Win32Exception wex)
            {
                LogWriteLine(wex.Message, Options.Global.LogLevel.Error);
            }
            catch (System.Exception ex)
            {
                LogWriteLine(ex.ToString(), Options.Global.LogLevel.Assert);
            }
            finally
            {
            }
        }

        /// <summary>
        /// Stops service
        /// </summary>
        private void StopService()
        {
            try
            {
                CheckServiceSatus();

                if (Utils.ServiceMangerInternal.LastServiceStatus.dwCurrentState == (int)Utils.ServiceMangerInternal.ServiceCurrentState.SERVICE_PAUSED
                    || Utils.ServiceMangerInternal.LastServiceStatus.dwCurrentState == (int)Utils.ServiceMangerInternal.ServiceCurrentState.SERVICE_RUNNING)
                {
                    LogWriteLine("Stopping ndisprot", Options.Global.LogLevel.Info); 

                    CloseAdapter();

                    Utils.ServiceMangerInternal.StopService(Utils.ServiceMangerInternal.NdisProtServiceName);

                    WaitForServiceState(Utils.ServiceMangerInternal.ServiceCurrentState.SERVICE_STOPPED, 1);

                    LogWriteLine("Success", Options.Global.LogLevel.Info); 

                    CheckServiceSatus();
                }
                else
                {
                    LogWriteLine("Not supported service state for stopping", Options.Global.LogLevel.Error);
                }
            }
            catch (Win32Exception wex)
            {
                LogWriteLine(wex.Message, Options.Global.LogLevel.Error);
            }
            catch (System.Exception ex)
            {
                LogWriteLine(ex.ToString(), Options.Global.LogLevel.Assert);
            }
            finally
            {
            }
        }

        /// <summary>
        /// Pausing service
        /// </summary>
        private void PauseService()
        {
            try
            {
                CheckServiceSatus();
                if (Utils.ServiceMangerInternal.LastServiceStatus.dwCurrentState == (int)Utils.ServiceMangerInternal.ServiceCurrentState.SERVICE_RUNNING)
                {

                    LogWriteLine("Pausing ndisprot", Options.Global.LogLevel.Info); 

                    CloseAdapter();

                    Utils.ServiceMangerInternal.PauseService(Utils.ServiceMangerInternal.NdisProtServiceName);

                    WaitForServiceState(Utils.ServiceMangerInternal.ServiceCurrentState.SERVICE_PAUSED, 2);

                    LogWriteLine("Success", Options.Global.LogLevel.Info);

                    CheckServiceSatus();
                }
                else
                {
                    LogWriteLine("Not supported service state for pausing", Options.Global.LogLevel.Error);
                }
            }
            catch (Win32Exception wex)
            {
                LogWriteLine(wex.Message, Options.Global.LogLevel.Error);
            }
            catch (System.Exception ex)
            {
                LogWriteLine(ex.ToString(), Options.Global.LogLevel.Assert);
            }
            finally
            {
            }
        }

        /// <summary>
        /// Continue service
        /// </summary>
        private void ContinueService()
        {
            try
            {
                CheckServiceSatus();
                if (Utils.ServiceMangerInternal.LastServiceStatus.dwCurrentState == (int)Utils.ServiceMangerInternal.ServiceCurrentState.SERVICE_PAUSED)
                {
                    LogWriteLine("Continuing ndisprot", Options.Global.LogLevel.Info); 

                    CloseAdapter();

                    Utils.ServiceMangerInternal.ContinueService(Utils.ServiceMangerInternal.NdisProtServiceName);

                    WaitForServiceState(Utils.ServiceMangerInternal.ServiceCurrentState.SERVICE_RUNNING, 2);

                    LogWriteLine("Success", Options.Global.LogLevel.Info);

                    InitAdapter();

                    CheckServiceSatus();
                }
                else
                {
                    LogWriteLine("Not supported service state for Continue", Options.Global.LogLevel.Error);
                }
            }
            catch (Win32Exception wex)
            {
                LogWriteLine(wex.Message, Options.Global.LogLevel.Error);
            }
            catch (System.Exception ex)
            {
                LogWriteLine(ex.ToString(), Options.Global.LogLevel.Assert);
            }
            finally
            {
            }
        }

        /// <summary>
        /// Restarts ndisprot service
        /// </summary>
        private void RestartService()
        {
            try
            {
                StopService();
                StartService();
                   
            }
            catch (Win32Exception wex)
            {
                LogWriteLine(wex.Message , Options.Global.LogLevel.Error);
            }
            catch (System.Exception ex)
            {
                LogWriteLine(ex.ToString(), Options.Global.LogLevel.Assert);
            }
            finally
            {
            }
        }

        /// <summary>
        /// Checking NdisProt service status
        /// </summary>
        private void CheckServiceSatus()
        {
            pauseToolStripMenuItem.Enabled = false;
            startToolStripMenuItem.Enabled = false;
            stopToolStripMenuItem.Enabled = false;
            restartToolStripMenuItem.Enabled = false;

            try
            {
                if (IsNdisprotServiceInstalled())
                {
                    Utils.ServiceMangerInternal.GetServiceStatus(Utils.ServiceMangerInternal.NdisProtServiceName);

                    if (Utils.ServiceMangerInternal.LastServiceStatus.dwCurrentState == (int)Utils.ServiceMangerInternal.ServiceCurrentState.SERVICE_RUNNING)
                    {
                        startToolStripMenuItem.Text = "Start";

                        pauseToolStripMenuItem.Enabled = true;
                        startToolStripMenuItem.Enabled = false;
                        stopToolStripMenuItem.Enabled = true;
                        restartToolStripMenuItem.Enabled = true;

                        serviceStatusLabel.Text = "Status: Ndisprot Running";
                    }
                    else if (Utils.ServiceMangerInternal.LastServiceStatus.dwCurrentState == (int)Utils.ServiceMangerInternal.ServiceCurrentState.SERVICE_PAUSED)
                    {
                        startToolStripMenuItem.Text = "Continue";

                        pauseToolStripMenuItem.Enabled = false;
                        startToolStripMenuItem.Enabled = true;
                        stopToolStripMenuItem.Enabled = true;
                        restartToolStripMenuItem.Enabled = true;

                        serviceStatusLabel.Text = "Status: Ndisprot paused";
                    }
                    else if (Utils.ServiceMangerInternal.LastServiceStatus.dwCurrentState == (int)Utils.ServiceMangerInternal.ServiceCurrentState.SERVICE_STOPPED)
                    {
                        startToolStripMenuItem.Text = "Start";

                        pauseToolStripMenuItem.Enabled = false;
                        startToolStripMenuItem.Enabled = true;
                        stopToolStripMenuItem.Enabled = false;
                        restartToolStripMenuItem.Enabled = false;

                        serviceStatusLabel.Text = "Status: Ndisprot Stopped";
                    }
                }
            }
            catch (Win32Exception wex)
            {
                LogWriteLine(wex.Message, Options.Global.LogLevel.Error);
            }
            catch (System.Exception ex)
            {
                LogWriteLine(ex.ToString(), Options.Global.LogLevel.Assert);
            }
            finally
            {
            }
        }

        /// <summary>
        /// INstalls ndisprot service on local computer
        /// </summary>
        private void InstallService()
        {
            try
            {
                Utils.ServiceMangerInternal.InstallService();
            }
            catch (Win32Exception wex)
            {
                LogWriteLine(wex.Message, Options.Global.LogLevel.Error);
            }
            catch (System.Exception ex)
            {
                LogWriteLine(ex.ToString(), Options.Global.LogLevel.Assert);
            }
            finally
            {
            }
        }

        /// <summary>
        /// Remove ndisprot service on local computer
        /// </summary>
        private void RemoveService()
        {
            try
            {
                Utils.ServiceMangerInternal.RemoveService();
            }
            catch (Win32Exception wex)
            {
                LogWriteLine(wex.Message, Options.Global.LogLevel.Error);
            }
            catch (System.Exception ex)
            {
                LogWriteLine(ex.ToString(), Options.Global.LogLevel.Assert);
            }
            finally
            {
            }
        }

        /// <summary>
        /// Checks if ndisprot service is installed
        /// </summary>
        /// <returns></returns>
        private bool IsNdisprotServiceInstalled()
        {
            installServiceToolStripMenuItem.Enabled = false;
            removeServiceToolStripMenuItem.Enabled = false;

            System.ServiceProcess.ServiceController[] Scs = System.ServiceProcess.ServiceController.GetDevices();

            foreach (System.ServiceProcess.ServiceController sc in Scs)
            {
                if (sc.ServiceName.Equals(Utils.ServiceMangerInternal.NdisProtServiceName, StringComparison.CurrentCultureIgnoreCase))
                {
                    installServiceToolStripMenuItem.Enabled = false;
                    removeServiceToolStripMenuItem.Enabled = true;
                    return true;
                }
            }

            installServiceToolStripMenuItem.Enabled = true;
            removeServiceToolStripMenuItem.Enabled = false;
            return false;
        }
      
        /// <summary>
        /// Thread Wait for service state
        /// </summary>
        /// <param name="targetState">State what we waiting for</param>
        /// <param name="timeOut">Timeout in seconds</param>
        private void WaitForServiceState(Utils.ServiceMangerInternal.ServiceCurrentState targetState, int timeOut)
        {
            this.CurrentTimes = 0;
            this.TimeOut = timeOut;

            WaitingState = targetState;
            EventTimer.Enabled = true;
        }
      
        #endregion

        #region Methods : Log

        /// <summary>
        /// Initialize behaviour of UI controls any how connected with options log level
        /// </summary>
        private void InitLogLevelOptions()
        {
            foreach (Options.Global.LogLevel ll in Enum.GetValues(typeof(Options.Global.LogLevel)))
            {
                OutputMessages.Add(ll, new List<string>());
            }

            logLevelToolStripMenuItem.DropDownItemClicked += new ToolStripItemClickedEventHandler(logLevelToolStripMenuItem_DropDownItemClicked);

            debugToolStripMenuItem.Tag = Options.Global.LogLevel.Debug;
            infoToolStripMenuItem.Tag = Options.Global.LogLevel.Info;
            warningToolStripMenuItem.Tag = Options.Global.LogLevel.Warning;
            errorToolStripMenuItem.Tag = Options.Global.LogLevel.Error;
            assertToolStripMenuItem.Tag = Options.Global.LogLevel.Assert;
        }

        /// <summary>
        /// Draws log into textbox
        /// </summary>
        private void ViewLog()
        {
            Instance.textBox_log.Lines = OutputMessages[Options.Global.CurrentLogLevel].ToArray();
        }
        #endregion 

        #region Methods : Common
        private void InitCommonControls()
        {
        }
        #endregion

        #endregion

        #region Public Methods

        public static void LogWriteLine(String line, Options.Global.LogLevel logLevel = Options.Global.LogLevel.Debug)
        {
            lock (OutputMessages)
            {
                int iLogLevel = (int)logLevel;

                if (iLogLevel >= (int)Options.Global.LogLevel.Debug)
                {
                    OutputMessages[Options.Global.LogLevel.Debug].Add(String.Format("{0} : {1}", DateTime.Now, line));
                }
                if (iLogLevel >= (int)Options.Global.LogLevel.Info)
                {
                    OutputMessages[Options.Global.LogLevel.Info].Add(String.Format("{0} : {1}", DateTime.Now, line));
                }
                if (iLogLevel >= (int)Options.Global.LogLevel.Warning)
                {
                    OutputMessages[Options.Global.LogLevel.Warning].Add(String.Format("{0} : {1}", DateTime.Now, line));
                }
                if (iLogLevel >= (int)Options.Global.LogLevel.Error)
                {
                    OutputMessages[Options.Global.LogLevel.Error].Add(String.Format("{0} : {1}", DateTime.Now, line));
                }
                if (iLogLevel >= (int)Options.Global.LogLevel.Assert)
                {
                    OutputMessages[Options.Global.LogLevel.Assert].Add(String.Format("{0} : {1}", DateTime.Now, line));
                }
            }

            MainWindow.Instance.Invoke(new EthernetTools.Utils.Delegates.VoidDelegate(MainWindow.Instance.ViewLog));
        }

        public static void DebugLog(byte[] arr)
        {
            LogWriteLine(EthernetTools.Utils.ByteUtils.ByteArrToString(arr), Options.Global.LogLevel.Debug);
        }

        #endregion

        #region Event handlers

        #region  Events : Form

        private void MainWindow_Load(object sender, EventArgs e)
        {
            IsNdisprotServiceInstalled();

            CheckServiceSatus();

            InitAdapter();

            InitCommonControls();
        }

        private void MainWindow_FormClosing(object sender, FormClosingEventArgs e)
        {
            CloseAdapter();
        }

        /// <summary>
        /// Hide to tray on minimized
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainWindow_SizeChanged(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                Hide();
            }
        }
        #endregion

        #region  Events : Controls

        private void EventTimer_Tick(object sender, EventArgs e)
        {
            if (this.CurrentTimes > this.TimeOut)
            {
                CurrentTimes = 0;
                EventTimer.Enabled = false;

                ServiceStateEvent.Set();

                LogWriteLine("After " + TimeOut + " seconds, service not change state to " + WaitingState.ToString(), Options.Global.LogLevel.Debug);
            }
            else
            {
                CheckServiceSatus();
                if (Utils.ServiceMangerInternal.LastServiceStatus.dwCurrentState == (int)this.WaitingState)
                {
                    ServiceStateEvent.Set();
                    EventTimer.Enabled = false;
                    this.CurrentTimes = 0;
                }
            }

            ++this.CurrentTimes;
        }

        private void listBox_adapters_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            this.BindAdapter();
        }

        private void textBox_log_TextChanged(object sender, EventArgs e)
        {
            if (Options.Global.AutoScrollLog)
            {
                caretPosition = this.textBox_log.Text.Length;
            }
            this.textBox_log.Select(caretPosition, 0);
            this.textBox_log.ScrollToCaret();
            this.textBox_log.DeselectAll();
        }

        private void LogContextMenu_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            if (e.ClickedItem == toolStripMenuItem_clearLog)
            {
                lock (OutputMessages)
                {
                    foreach (KeyValuePair<Options.Global.LogLevel, List<string>> logMessages in OutputMessages)
                    {
                        logMessages.Value.Clear();
                    }
                }

                ViewLog();
            }

        }

        private void toolStripMenuItem_autoscrollLog_CheckedChanged(object sender, EventArgs e)
        {
            Options.Global.AutoScrollLog = toolStripMenuItem_autoscrollLog.Checked;
        }

        private void LogContextMenu_Opening(object sender, CancelEventArgs e)
        {
            toolStripMenuItem_autoscrollLog.Checked = Options.Global.AutoScrollLog;
        }
        #endregion

        #region Events : Tray
        private void notifyIcon_mainWindow_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            Show();
            this.WindowState = FormWindowState.Normal;
        }

        private void notifyIcon_mainWindow_MouseMove(object sender, MouseEventArgs e)
        {
            if (BindedAdapterId != null)
            {
                // max 64 symbols
                this.notifyIcon_mainWindow.Text = "Current state: Reading." + Environment.NewLine
                    + " Already read: " + EthernetTools.UI.TabPppoeAcMap.ReadSize;
            }
            else
            {
                this.notifyIcon_mainWindow.Text = "Waiting.";
            }
        }

        #endregion

        #region Events : Main Menu

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void restartToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show(
                this,
                "This will restarts NdisProt Driver, all current connections will be dropped." + Environment.NewLine + "Continue?",
                "Restart NdiProt service?",
                MessageBoxButtons.YesNoCancel,
                MessageBoxIcon.Warning) == DialogResult.Yes)
            {
                RestartService();
            }
        }

        private void startToolStripMenuItem_Click(object sender, EventArgs e)
        {
            StartService();
        }

        private void pauseToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show(
                this,
                "This will pause NdisProt Driver, all current connections PROBABLY will be dropped." + Environment.NewLine + "Continue?",
                "Pause NdiProt service?",
                MessageBoxButtons.YesNoCancel,
                MessageBoxIcon.Warning) == DialogResult.Yes)
            {
                PauseService();
            }
        }

        private void stopToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show(
                   this,
                   "This will stops NdisProt Driver, all current connections will be dropped." + Environment.NewLine + "Continue?",
                   "Stop NdiProt service?",
                   MessageBoxButtons.YesNoCancel,
                   MessageBoxIcon.Warning) == DialogResult.Yes)
            {
                StopService();
            }
        }

        private void fullRefreshToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void logLevelToolStripMenuItem_DropDownItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            debugToolStripMenuItem.Checked = e.ClickedItem == debugToolStripMenuItem;
            infoToolStripMenuItem.Checked = e.ClickedItem == infoToolStripMenuItem;
            warningToolStripMenuItem.Checked = e.ClickedItem == warningToolStripMenuItem;
            errorToolStripMenuItem.Checked = e.ClickedItem == errorToolStripMenuItem;
            assertToolStripMenuItem.Checked = e.ClickedItem == assertToolStripMenuItem;

            try
            {
                Options.Global.LogLevel ll = (Options.Global.LogLevel)e.ClickedItem.Tag;
                Options.Global.CurrentLogLevel = ll;
                ViewLog();
            }
            catch (System.Exception)
            {
            	
            }
        }

        private void installServiceToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!IsNdisprotServiceInstalled())
            {
                if (MessageBox.Show(
                  this,
                  "This will install NdisProt Driver at your computer." + Environment.NewLine + "Continue?",
                  "Install NdiProt?",
                  MessageBoxButtons.YesNoCancel,
                  MessageBoxIcon.Warning) == DialogResult.Yes)
                {
                    InstallService();

                    CheckServiceSatus();

                    LogWriteLine("INstall complete. Now try to start it", Options.Global.LogLevel.Info);
                }
            }
            else
            {
                LogWriteLine("Service already installed", Options.Global.LogLevel.Error);
            }
        }

        private void removeServiceToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (IsNdisprotServiceInstalled())
            {
                if (MessageBox.Show(
                  this,
                  "This will Remove NdisProt Driver from your computer." + Environment.NewLine + "Continue?",
                  "Remove NdiProt?",
                  MessageBoxButtons.YesNoCancel,
                  MessageBoxIcon.Warning) == DialogResult.Yes)
                {
                    CloseAdapter();

                    StopService();

                    RemoveService();

                    CheckServiceSatus();

                    LogWriteLine("Remove complete.", Options.Global.LogLevel.Info);
                }
            }
            else
            {
                LogWriteLine("Can't find service on local machine", Options.Global.LogLevel.Error);
            }
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            UI.Dialogs.AboutDialog ad = new UI.Dialogs.AboutDialog();
            ad.ShowDialog(this);
        }

        private void prefencesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            PreferencesDialog pd = new PreferencesDialog();
            pd.ShowDialog();
        }

        private void helpToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                System.Diagnostics.Process.Start(Options.Global.HelpUrl);
            }
            catch(System.ComponentModel.Win32Exception noBrowser)
            {
                if (noBrowser.ErrorCode == -2147467259)
                    MessageBox.Show(noBrowser.Message);
            }
        }

        private void clearPacketQueueToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Packets.PacketQueue.Clear();
        }

        private void highestToolStripMenuItem_Click(object sender, EventArgs e)
        {
            highestToolStripMenuItem.Checked = true;
            aboveNormalToolStripMenuItem.Checked = false;
            normalToolStripMenuItem.Checked = false;
            belowNormalToolStripMenuItem.Checked = false;
            lowestToolStripMenuItem.Checked = false;

            EthernetTools.UI.TabPppoeAcMap.ReadingPriority = ThreadPriority.Highest;
        }

        private void aboveNormalToolStripMenuItem_Click(object sender, EventArgs e)
        {
            highestToolStripMenuItem.Checked = false;
            aboveNormalToolStripMenuItem.Checked = true;
            normalToolStripMenuItem.Checked = false;
            belowNormalToolStripMenuItem.Checked = false;
            lowestToolStripMenuItem.Checked = false;

            EthernetTools.UI.TabPppoeAcMap.ReadingPriority = ThreadPriority.AboveNormal;
        }

        private void normalToolStripMenuItem_Click(object sender, EventArgs e)
        {
            highestToolStripMenuItem.Checked = false;
            aboveNormalToolStripMenuItem.Checked = false;
            normalToolStripMenuItem.Checked = true;
            belowNormalToolStripMenuItem.Checked = false;
            lowestToolStripMenuItem.Checked = false;

            EthernetTools.UI.TabPppoeAcMap.ReadingPriority = ThreadPriority.Normal;
        }

        private void belowNormalToolStripMenuItem_Click(object sender, EventArgs e)
        {
            highestToolStripMenuItem.Checked = false;
            aboveNormalToolStripMenuItem.Checked = false;
            normalToolStripMenuItem.Checked = false;
            belowNormalToolStripMenuItem.Checked = true;
            lowestToolStripMenuItem.Checked = false;

            EthernetTools.UI.TabPppoeAcMap.ReadingPriority = ThreadPriority.BelowNormal;
        }

        private void lowestToolStripMenuItem_Click(object sender, EventArgs e)
        {
            highestToolStripMenuItem.Checked = false;
            aboveNormalToolStripMenuItem.Checked = false;
            normalToolStripMenuItem.Checked = false;
            belowNormalToolStripMenuItem.Checked = false;
            lowestToolStripMenuItem.Checked = true;

            EthernetTools.UI.TabPppoeAcMap.ReadingPriority = ThreadPriority.Lowest;
        }
        #endregion
                
        #endregion
    }
}
